_Pragma("once")

#include "DeviceCommunicator.h"
#include <sstream>
#include <iostream>
#include "StringUtility.h"

class SpiCommunicator : public DeviceCommunicator {
public:
    static constexpr uint32_t SPEED = 1 * 1000* 1000;
    static constexpr size_t DEBUG_OUTPUT_SIZE = 100;

    /** Default constructor */
    SpiCommunicator(const std::string& deviceName = "/dev/spidev0.0"): DeviceCommunicator(deviceName) {
        initialize();
    }
    /** Default destructor */
    ~SpiCommunicator();

    ssize_t write1(const std::string& exceptionTip, void const * const data, const size_t size) noexcept;


    virtual ssize_t write(const std::string& exceptionTip, void const * const data, const size_t size) noexcept override {

        ssize_t written = 0;
        written = ::write(deviceFd, data, size);

        const size_t debugSize = std::min(DEBUG_OUTPUT_SIZE, size);
        std::string binaryString{"send:"};
        StringUtility::dumpMemory((uint8_t*)data, debugSize, "%u,", binaryString);
        binaryString.append(",string:").append((const char*)data, debugSize);
        binaryString.append(",written:");
        std::cout << binaryString << written << std::endl;
        return written;
    }

    ssize_t read(const std::string& exceptionTip, void * buffer, const size_t length) noexcept override;

    ssize_t read0(const std::string& exceptionTip, void * buffer, const size_t length) noexcept;

    bool initialize(uint8_t mode = 0, uint8_t bits = 8, uint32_t speed = SPEED);

protected:
};
